
/*
 * @Author: ljkt
 * @Version: 2.0
 * @Date: 2021-12-01 14:27:01
 * @LastEditors: ljkt
 * @LastEditTime: 2025-02-08 21:35:58
 * @Description:
 */

#include "./Common_Include.h"
#ifdef EN_COM_SEG
Ram s_drv_comseg_t gDrv_ComSeg;
CONST s_segx_config_t segx_config_tab[e_INDEX_SEG_MAX] = DRV_SEGX_CONFIG_TAB;
CONST s_comx_config_t comx_config_tab[e_INDEX_COM_MAX] = DRV_COMX_CONFIG_TAB;
void Drv_ComSeg_Init(void)
{
    unsigned char i;
    s_segx_config_t *segx_config = segx_config_tab;
    s_comx_config_t *comx_config = comx_config_tab;
    memset(&gDrv_ComSeg, 0, sizeof(s_drv_comseg_t));
    for (i = 0; i < ARR_CNT(segx_config_tab); i++)
    {
        Hal_Gpio_Out(&segx_config->gpio, segx_config->level[0]);
        segx_config++;
    }
    for (i = 0; i < ARR_CNT(comx_config_tab); i++)
    {
        Hal_Gpio_Out(&comx_config_tab->gpio, comx_config_tab->level[0]);
        comx_config++;
    }
}
/**
 * @brief 更新数码管显示缓冲区
 *
 * 该函数用于将全局缓冲区的数据复制到中断服务程序缓冲区，以便在中断服务程序中更新数码管的显示内容。
 * 在复制数据之前，会先关闭全局中断，以防止数据被中断服务程序修改。复制完成后，再打开全局中断。
 *
 * @param void 无参数
 * @return void 无返回值
 */
void Drv_ComSeg_Update(void)
{
    // 关闭全局中断，防止数据被中断服务程序修改
    SET_GLOBAL_IE(REF_FALSE);
    // 将全局缓冲区的数据复制到中断服务程序缓冲区
    memcpy(&gDrv_ComSeg.Buf_Isr, &gDrv_ComSeg.Buf, sizeof(gDrv_ComSeg.Buf));
    // 打开全局中断
    SET_GLOBAL_IE(REF_TRUE);
}
/**

/**
 * @brief 数码管显示中断服务程序
 *
 * 该函数用于在中断服务程序中更新数码管的显示内容。
 * 它通过循环扫描的方式，依次点亮每个数码管，并显示相应的数据。
 */
void Drv_ComSeg_Isr(void)
{
    // 获取指定索引的IOO配置
    s_segx_config_t *segx_config = segx_config_tab;
    s_comx_config_t *comx_config = comx_config_tab;

    static unsigned char comx_index = 0;
    Ram unsigned char dat;
    Ram unsigned char i;

    // 关当前亮着的comx
    comx_config = &comx_config_tab[comx_index];
    Hal_Gpio_Set_Isr(&comx_config->gpio, comx_config->level[0]);
    LIMIT_CYCLE_ADD(comx_index, e_INDEX_COM_MAX - 1);
    // 获取要显示的数据
    dat = gDrv_ComSeg.Buf_Isr[comx_index];
    // 获取新的comx配置
    comx_config = &comx_config_tab[comx_index];
    for (i = 0; i < e_INDEX_SEG_MAX; i++)
    {
        Hal_Gpio_Set_Isr(&segx_config->gpio, segx_config->level[dat & 0x01]);
        dat = dat >> 1;
    }
    // 打开新的comx
    Hal_Gpio_Set_Isr(&comx_config->gpio, comx_config->level[1]);
}
/**
 * @brief 数码管显示占空比中断服务程序
 *
 * 该函数用于在中断服务程序中更新数码管的显示内容，根据占空比控制显示的亮度。
 * 它通过循环扫描的方式，依次点亮每个数码管，并显示相应的数据。
 *
 * @param duty 占空比，用于控制数码管的亮度
 */
void Drv_ComSeg_Duty_Isr(unsigned char duty)
{
    // 获取指定索引的IOO配置
    s_segx_config_t *segx_config = segx_config_tab;
    s_comx_config_t *comx_config = comx_config_tab;

    // 静态变量，用于记录当前的占空比计数
    static Ram unsigned char duty_cnt = 0;
    // 静态变量，用于记录当前正在显示的数码管索引
    static Ram unsigned char comx_index;
    // 临时变量，用于存储要显示的数据
    Ram unsigned char dat, level, i;

    // 关闭当前亮着的数码管
    comx_config = &comx_config_tab[comx_index];
    Hal_Gpio_Set_Isr(&comx_config->gpio, comx_config->level[0]);
    // 更新占空比计数，循环显示
    LIMIT_CYCLE_ADD(duty_cnt, e_INDEX_COM_MAX * DRV_SEG_COM_DUTY_MAX);
    // 根据占空比计算当前要显示的数码管索引
    comx_index = duty_cnt % e_INDEX_COM_MAX;
    level = duty / e_INDEX_COM_MAX;
    // 获取要显示的数据
    dat = ((level < duty) ? (gDrv_ComSeg.Buf_Isr[comx_index]) : (0));
    // 获取新的comx配置
    comx_config = &comx_config_tab[comx_index];
    // 依次点亮每个数码管，并显示相应的数据
    for (i = 0; i < e_INDEX_SEG_MAX; i++)
    {
        Hal_Gpio_Set_Isr(&segx_config->gpio, segx_config->level[dat & 0x01]);
        dat = dat >> 1;
    }
    // 打开新的数码管
    Hal_Gpio_Set_Isr(&comx_config->gpio, comx_config->level[1]);
}

#endif
